home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 49
/
Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso
/
Aminet
/
dev
/
gui
/
Feelin.lha
/
Feelin
/
Class3.e
< prev
next >
Wrap
Text File
|
2002-03-14
|
7KB
|
216 lines
OPT PREPROCESS
MODULE 'intuition/intuition',
'feelin','libraries/feelin','a4'
-> This is the instance data for our custom class.
OBJECT mydata
x:INT,y:INT
sx:INT,sy:INT
ENDOBJECT
PROC main()
DEF c,w,myobj,
fcc:PTR TO feelinClass
sys_SGlob()
IF feelinbase := OpenLibrary('feelin.library',FV_VERSION)
/*
Create the new custom class with a call to F_CreateClass().
This function returns a feelinClass structure. You must use class.id to
create instance of your custom class. This ID is unique and made by
F_CreateClass() when ID is NIL.
*/
IF fcc := F_CreateClass(NIL,FC_Area,NIL,SIZEOF mydata,{myDispatcher})
c := ClientObject,
Child, w := WindowObject, FA_Window_Title, 'A rather complex custom class',
Child, VGroup, NoFrame,
Child, TextObject, FA_FixedHeight,TRUE, DontChain, TextFrame, TextBack, FA_Text, '`c`iPaint `nwith `bmouse`n,\n`iScroll `nwith `bcursor keys`n.', End,
Child, myobj := F_NewObjA(fcc.id,[TextFrame, TAG_DONE]),
End,
FA_Window_ActiveObject, myobj, -> Safe here
End,
End
IF c
F_DoA(w,FM_Notify,[FA_Window_CloseRequest,TRUE, c,2,FM_Client_ReturnID,FV_Client_Quit])
F_Set(w,FA_Window_Open,TRUE)
WHILE F_DoA(c,FM_Client_WaitEvent,NIL) <> FV_Client_Quit DO NOP
F_DisposeObj(c)
ENDIF
F_RemoveClass(fcc)
ELSE
WriteF('Could not create custom class.\n')
ENDIF
CloseLibrary(feelinbase)
ELSE
WriteF('Failed to open feelin.library\n')
ENDIF
ENDPROC
PROC myDispatcher(cl=A2:PTR TO feelinClass,obj=A0:PTR TO feelinObject,method=D0,args=A1:PTR TO LONG)
DEF data:PTR TO mydata
sys_RGlob() ; data := INST_DATA(cl,obj)
/*
Here comes the dispatcher for our custom class. Unknown/unused methods are
passed to the superclass immediately.
*/
SELECT method
CASE FM_AskMinMax ; mAskMinMax (cl,obj)
CASE FM_Draw ; mDraw (cl,obj,data,args)
CASE FM_HandleEvent ; RETURN mHandleEvent (obj,data,args)
CASE FM_Active ; mActive (cl,obj,TRUE)
CASE FM_Inactive ; mActive (cl,obj,FALSE)
DEFAULT ; RETURN F_SuperDoA (cl,obj,method,args)
ENDSELECT
ENDPROC
PROC mAskMinMax(cl,obj:PTR TO feelinObject)
/*
Area.AskMinMax() will be called before the window is opened. We need to
tell Feelin the minimum and maximum size of our object.
When you are the first receiving the method the fields _minw() and
_minh() are set to zero and the fields _maxw() and _maxh() to FV_MAXMAX.
We can add values to _minw() and _minh() or set _maxw() and _maxh() if
we need to. Then we pass the method to our superclass.
When the method reaches Area class these values will be adjusted
according to FA_MinXxx, FA_FixedXxx and FA_FixXxx attributes.
*/
_minw(obj) += 100 ; _minh(obj) += 40
_maxw(obj) := 500 ; _maxh(obj) := 300
F_SuperDoA(cl,obj,FM_AskMinMax,NIL)
ENDPROC
PROC mDraw(cl,obj:PTR TO feelinObject,data:PTR TO mydata,d:PTR TO FS_Draw)
/*
Draw method is called whenever Feelin feels (obviously ;-)) we should
render our object. This usually happens after layout is finished. Note:
You may only render within the rectangle _mleft(), _mtop(), _mwidth(),
_mheight().
*/
DEF rp
/*
Let our superclass draw itself first, Area class would e.g. draw the
frame and clear the whole region. What it does exactly depends on flags.
*/
F_SuperDoA(cl,obj,FM_Draw,d)
/*
IF FF_Draw_Object isn't set, we shouldn't draw anything. Feelin just
wanted to update the frame or something like that.
*/
rp := _rp(obj)
IF d.flags AND FF_Draw_Update -> called from our input method
IF data.sx OR data.sy
_BPen(_pen(obj,FV_Pen_Shine))
ScrollRaster(rp,data.sx,data.sy,_mleft(obj),_mtop(obj),_mright(obj),_mbottom(obj))
_BPen(_pen(obj,FV_Pen_Dark))
data.sx := NIL
data.sy := NIL
ELSE
_APen(_pen(obj,FV_Pen_Shadow))
_Plot(data.x,data.y)
ENDIF
ELSEIF d.flags AND FF_Draw_Object
_APen(_pen(obj,FV_Pen_Shine))
_Boxf(_mleft(obj),_mtop(obj),_mright(obj),_mbottom(obj))
ENDIF
ENDPROC
PROC mActive(cl,obj:PTR TO feelinObject,state)
/*
Area class always creates an EventHandler structure in case of some
inputmodes. As we handle events instead of Area class we can use it as
we want. It will save us some allocations ;-)
Using F_ModifyHandler() to modify IDCMP flags it's a piece of cake to
request IDCMP events.
*/
IF state
F_ModifyHandler(_handler(obj),IDCMP_RAWKEY OR IDCMP_MOUSEBUTTONS,NIL)
ELSE
F_ModifyHandler(_handler(obj),NIL,IDCMP_RAWKEY OR IDCMP_MOUSEBUTTONS)
ENDIF
F_SuperDoA(cl,obj,IF state THEN FM_Active ELSE FM_Inactive,NIL)
ENDPROC
PROC mHandleEvent(obj:PTR TO feelinObject,data:PTR TO mydata,he:PTR TO FS_HandleEvent)
/*
in mSetup() we said that we want get a message if mousebuttons or keys
pressed so we have to define the input-handler
Note :
This is really a good example, because it shows how to use critical
events carefully:
IDCMP_MOUSEMOVE is only needed when left-mousebutton is pressed, so we
dont request this until we get a SELECTDOWN-message and we reject
IDCMP_MOUSEMOVE immeditly after we get a SELECTUP-message
*/
#define _between(a,x,b) (x == [a TO b])
#define _isinobject(x,y) (_between(_mleft(obj),(x),_mright(obj)) AND _between(_mtop(obj),(y),_mbottom(obj)))
/*
Note on Arrows handling :
If you don't handle arrows return NIL, this will allow Window object to
cycle through its chain using arrows instead of tabulations (more
confortable hu ?), else return your object. Currently, result is only check
against NIL, but this may change in future, so return your object.
*/
IF he.key <> FK_NONE
SELECT he.key
CASE FK_LEFT ; data.sx := -1
CASE FK_RIGHT ; data.sx := 1
CASE FK_UP ; data.sy := -1
CASE FK_DOWN ; data.sy := 1
DEFAULT ; RETURN NIL
ENDSELECT
F_Draw(obj,FF_Draw_Update)
RETURN obj -> Forbid arrow cycling, because *WE* handle key events.
ELSEIF he.msg.class = IDCMP_MOUSEBUTTONS
IF he.msg.code = SELECTDOWN
IF _isinobject(he.msg.mousex,he.msg.mousey)
data.x := he.msg.mousex
data.y := he.msg.mousey
F_Draw(obj,FF_Draw_Update)
-> Only request IDCMP_MOUSEMOVE if we realy need it
F_ModifyHandler(_handler(obj),IDCMP_MOUSEMOVE,NIL)
ENDIF
ELSE
-> Reject IDCMP_MOUSEMOVE because lmb is no longer pressed
F_ModifyHandler(_handler(obj),NIL,IDCMP_MOUSEMOVE)
ENDIF
ELSEIF he.msg.class = IDCMP_MOUSEMOVE
IF _isinobject(he.msg.mousex,he.msg.mousey)
data.x := he.msg.mousex
data.y := he.msg.mousey
F_Draw(obj,FF_Draw_Update)
ENDIF
ENDIF
ENDPROC